package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.entity.ApComment;
import com.heima.comment.entity.ApCommentLike;
import com.heima.comment.entity.vo.ApCommentVo;
import com.heima.comment.service.ApCommentService;
import com.heima.feign.client.ApUserFeignClient;
import com.heima.greenScan.pojo.ScanResult;
import com.heima.greenScan.templete.BaiduAiTemplate;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.entity.ApUser;
import com.heima.utils.common.threadUtil.ThreadLocalUtil;
import com.heima.utils.common.threadUtil.UserInfo;
import org.apache.commons.lang.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class ApCommentServiceImpl implements ApCommentService {

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private BaiduAiTemplate baiduAiTemplate;

    @Resource
    private ApUserFeignClient apUserFeignClient;
    @Override
    public ResponseResult saveComment(String targetId, String content) {

        //从线程中获取用户id
        UserInfo userInfo = ThreadLocalUtil.get();
        if(userInfo==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //2.从redis中获取用户登录信息
        String user_info_key="USER_INFO_"+userInfo.getId();
        String user_info_json = stringRedisTemplate.opsForValue().get(user_info_key);
        ApUser apUser=null;


        if(StringUtils.isNotEmpty(user_info_json)){
            //如果缓存中存在用户信息
             apUser = JSON.parseObject(user_info_json, ApUser.class);
        }else{
            //缓存中不存在用户信息远程调用用户信息
            ResponseResult<ApUser> result = apUserFeignClient.findById(userInfo.getId().longValue());

            if(result.getCode()!=200||result.getData()==null){
                return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
            }
            apUser=result.getData();
            //缓存用户数据,保存24小时过期
            stringRedisTemplate.opsForValue().set(user_info_key,JSON.toJSONString(apUser), Duration.ofHours(24));

        }

        //对用户发布的文章进行审核
        //TODO 直接保存评论到信息库，发送异步审核，若审核不通过，删除数据库
        ScanResult scanResult = baiduAiTemplate.textScan(content);

        if(scanResult.getConclusionType()!=1){
        //当前审核不通过
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论中包含违规内容");
        }

        //封装评论数据
        ApComment apComment = new ApComment();
        apComment.setId(ObjectId.get().toHexString());
        apComment.setUserId(userInfo.getId().longValue());
        apComment.setNickName(apUser.getNicknme());
        apComment.setImage(apUser.getImage());
        apComment.setContent(content);
        apComment.setTargetId(targetId);
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());

        //保存数据到mongoDB;
        mongoTemplate.save(apComment);
        return ResponseResult.okResult("评论成功");
    }

    /**
     * 评论点赞
     * @param commentId 评论Id
     * @param operation 操作参数 0-点赞 1-取消点赞
     * @return
     */
    @Override
    public ResponseResult like(String commentId, Short operation) {

        UserInfo userInfo = ThreadLocalUtil.get();
        if(userInfo==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        String comment_like_key="COMMENT_LIKE_"+userInfo.getId();
        //判断当前用户是否点过赞
        Boolean flag = stringRedisTemplate.opsForSet().isMember(comment_like_key, commentId);

        //当前为未点赞 --点赞操作
        if(!flag&&operation==0){
            //新增点赞数据到数据库中
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setId(ObjectId.get().toHexString());
            apCommentLike.setTargetId(commentId);
            apCommentLike.setUserId(userInfo.getId());
            apCommentLike.setCreatedTime(new Date());

            //插入评论信息
            mongoTemplate.save(apCommentLike);

            //TODO 乐观锁解决点赞数混乱的问题
            //更新评论信息的点赞信息
            Query query = Query.query(Criteria.where("_id").is(commentId));
            Update update = new Update().inc("likes", 1);
            mongoTemplate.updateFirst(query,update,ApComment.class);

            //增加点赞数据到redis
            stringRedisTemplate.opsForSet().add(comment_like_key,commentId);
        }else if(flag&&operation==1){
            //已点赞,取消点赞行为
            //从redis删除数据
            stringRedisTemplate.opsForSet().remove(comment_like_key,commentId);

            //删除该用户对该文章的点赞数据
            Query query = Query.query(Criteria.where("userId").is(userInfo.getId()).and("targetId").is(commentId));
            mongoTemplate.remove(query,ApCommentLike.class);
            //更新评论数据 减少点赞数

            query=Query.query(Criteria.where("_id").is(commentId));
            Update update=new Update();
            update.inc("likes",-1);
            mongoTemplate.updateFirst(query,update,ApComment.class);

        }

        ApComment comment = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(commentId)), ApComment.class);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes", comment.getLikes());

        return ResponseResult.okResult(resultMap);
    }


    /**
     * 评论列表
     * @param targetId 文章id
     * @param minTime  最小时间
     * @param size
     * @return
     */
    @Override
    public ResponseResult<List<ApCommentVo>> load(String targetId, Date minTime, Integer size) {

        Query query = Query.query(Criteria.where("_id").is(targetId).and("createdTime").lt(minTime));
        List<ApComment> commentList = mongoTemplate.find(query, ApComment.class);
        UserInfo userInfo = ThreadLocalUtil.get();
        if(userInfo==null){
            return ResponseResult.okResult(commentList);
        }

        //用户登录了，获取用户对哪些评论点了赞
        String comment_like_key="COMMENT_LIKE_"+userInfo.getId();
        Set<String> members = stringRedisTemplate.opsForSet().members(comment_like_key);

        List<ApCommentVo> commentVoList = commentList.stream().map(comment -> {
            ApCommentVo apCommentVo = new ApCommentVo();
            //判断用户是否对该评论点过赞
            boolean flag = members.contains(comment.getId());

            if (flag) {
                //当前评论用户点过赞
                apCommentVo.setOperation((short) 0);
            } else {
                apCommentVo.setOperation((short) 1);
            }
            return apCommentVo;
        }).collect(Collectors.toList());

        //封装数据返回
        return ResponseResult.okResult(commentVoList);
    }

    @Override
    public ResponseResult saveCommentRepay(String targetId, String content) {

        ResponseResult result = saveComment(targetId, content);
        if(result.getCode()==200){
            //评论回复数+1
            Query query = Query.query(Criteria.where("_id").is(targetId));
            Update update = new Update();
            update.inc("likes",1);
            mongoTemplate.updateFirst(query,update,ApComment.class);
        }
        return result;
    }
}
